package org.mspring.platform.weibo.tencent;

import org.mspring.platform.weibo.tencent.entity.dto.TencentAuth;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.util.EntityUtils;
import org.mspring.platform.utils.http.HttpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 * 腾讯微博授权
 *
 * @author Gao Youbo
 * @since 2014年5月19日
 */
@Service
public class TencentOAuthService {

    private static final Logger log = LoggerFactory.getLogger(TencentOAuthService.class);

    private static final String AUTHORIZE_CODE_URL = "https://open.t.qq.com/cgi-bin/oauth2/authorize";

    private static final String ACCESS_TOKEN_URL = "https://open.t.qq.com/cgi-bin/oauth2/access_token";

    /**
     * 获取请求code的url
     *
     * @param clientId 申请应用时分配的app_key
     * @param redirectUri 授权回调地址，必须和应用注册的地址一致（地址长度上限为256个字节）
     * @return
     */
    public String getAuthorizeUrl(String clientId, String redirectUri) {
        Map<String, String> params = new HashMap<>();
        params.put("client_id", clientId);
        params.put("redirect_uri", redirectUri);
        params.put("response_type", "code");
        try {
            URIBuilder builder = new URIBuilder(AUTHORIZE_CODE_URL);
            for (Map.Entry<String, String> entry : params.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                builder.setParameter(key, value);
            }
            return builder.build().toString();
        } catch (URISyntaxException e) {
            log.error(null, e);
        }
        return null;
    }

    /**
     * 请求accessToken
     *
     * @param clientId 申请应用时分配的app_key
     * @param clientSecret 申请应用时分配的app_secret
     * @param code 调用authorize时返回的code
     * @param redirectUri 授权回调地址，必须和应用注册的地址一致（地址长度上限为256个字节）
     * @return
     * @throws Exception
     */
    public TencentAuth accessToken(String clientId, String clientSecret, String code, String redirectUri) throws Exception {
        String accessTokenUrl = getAccessTokenUrl(clientId, clientSecret, code, redirectUri);
        HttpResponse httpResponse = HttpUtils.get(accessTokenUrl);
        if (httpResponse == null || httpResponse.getStatusLine().getStatusCode() != 200) {
            throw new Exception("http请求失败");
        }
        String result = EntityUtils.toString(httpResponse.getEntity());
        return TencentAuth.getInstance(result);
    }

    /**
     * 获取请求accessToken的url
     *
     * @param clientId 申请应用时分配的app_key
     * @param clientSecret 申请应用时分配的app_secret
     * @param code 调用authorize时返回的code
     * @param redirectUri 授权回调地址，必须和应用注册的地址一致（地址长度上限为256个字节）
     * @return
     */
    public String getAccessTokenUrl(String clientId, String clientSecret, String code, String redirectUri) {
        Map<String, String> params = new HashMap<>();
        params.put("client_id", clientId);
        params.put("client_secret", clientSecret);
        params.put("code", code);
        params.put("redirect_uri", redirectUri);
        params.put("grant_type", "authorization_code");
        try {
            URIBuilder builder = new URIBuilder(ACCESS_TOKEN_URL);
            for (Map.Entry<String, String> entry : params.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                builder.setParameter(key, value);
            }
            return builder.build().toString();
        } catch (URISyntaxException e) {
            log.error(null, e);
        }
        return null;
    }

    /**
     * 获取刷新token的url
     *
     * @param clientId
     * @param refreshToken
     * @return
     */
    public String getRefreshTokenUrl(String clientId, String refreshToken) {
        Map<String, String> params = new HashMap<>();
        params.put("client_id", clientId);
        params.put("grant_type", "refresh_token");
        params.put("refresh_token", refreshToken);
        try {
            URIBuilder builder = new URIBuilder(ACCESS_TOKEN_URL);
            for (Map.Entry<String, String> entry : params.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                builder.setParameter(key, value);
            }
            return builder.build().toString();
        } catch (URISyntaxException e) {
            log.error(null, e);
        }
        return null;
    }

}
